/***************************************************************************
 *   oboe.controllers.SceneController					  *
 *   Copyright (C) 2011 by Felipe Manga					*
 *   lufeboma@gmail.com							*
 *									 *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the	   *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to	*
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:						 *
 *									 *
 *   The above copyright notice and this permission notice shall be	*
 *   included in all copies or substantial portions of the Software.	   *
 *									 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,	   *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF	*
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR	 *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.					   *
 ***************************************************************************/

package oboe.controllers;

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;

import oboe.core.Controller;
import oboe.core.SigSlot;
import oboe.core.SigSlotCollection;
import oboe.math.Number3D;
import oboe.math.Rotator;

import flash.Vector;

class SceneController extends Controller
{
public static inline var _camera_position:Float3D = new Number3D(0,0,0);
public static var _camera_rotator:Rotator;

private var rotator:Rotator;

private var childNodes:Vector<NodeController>;

private var minimumNodeIndex:Int;

private var camera_position:Float3D;
private var camera_rotation:Float3D;

public function new( displayObject:DisplayObject=null )
{
	super(displayObject);
	this.childNodes = new Vector();
	this.rotator = new Rotator(0,0,0);
	this.minimumNodeIndex = 0;
	this.camera_position = new Number3D(0,0,0);
	this.camera_rotation = new Number3D(0,0,0);
}

protected override function addChild(child:SigSlotCollection):Void
{
	if( child is NodeController ) this.childNodes.push( child );
	super.addChild( child );
}

protected override function removeChild(child:SigSlotCollection):Void
{
	if( child is NodeController )
	{
	var i:Int = this.childNodes.indexOf( child );
	if( i > -1 )
	{
		this.childNodes[i] = this.childNodes[ this.childNodes.length-1 ];
		this.childNodes.pop();
	}
	}
	
	super.removeChild( child );
}

private function render():Void
{
	if( this.camera_rotation )
	{
	_camera_rotator = this.rotator;
	if( !this.rotator.isEqual( this.camera_rotation ) )
	{
		this.rotator.copy2( -this.camera_rotation.x, -this.camera_rotation.y, -this.camera_rotation.z );
		this.rotator.update();
	}
	}
	else
	{
	_camera_rotator = null;
	}
	
	_camera_position.copy3( this.camera_position );
	
	this.childNodes.sort(
	function (a:NodeController, b:NodeController):Float
	{
		var r:Float = b.callGetZSortPosition() - a.callGetZSortPosition();
		if( r < 0 ) return -1;
		if( r > 0 ) return 1;
		return 0;
	}
	);
	
	var container:DisplayObjectContainer = this.getDisplayObject() as DisplayObjectContainer;
	var i:Int = this.minimumNodeIndex;
	
	for each( var child:NodeController in this.childNodes )
	{
	container.setChildIndex( child.target, i++ );
	}
}
}